home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 June: ROMin Holiday / ADC Developer CD (1992-06) (''ROMin Holiday'')_iso / Developer Connection - 06-1992.iso / Development Platforms / Apple II / Essentials / Dynamo 4.2 for GSBug 1.5b10 / buildapp.manual.text < prev    next >
Encoding:
Text File  |  1990-09-21  |  51.1 KB  |  1,240 lines  |  [TEXT/MPS ]

  1. Getting started:    Setting up the DYNAMO cross-development system:
  2.                     <<< Version 4.2 >>>
  3.  
  4.  
  5. NOTE:  Read the READ.ME file for Dynamo.  The installation instructions
  6. will be found there.
  7.  
  8.  
  9.  
  10. Now that we are installed, what did we install?
  11.  
  12.  
  13.  
  14. First, information on BUILDAPP.SYSTEM:
  15.  
  16.  
  17. The BUILDAPP.SYSTEM program allows the developer to build a multiple-segment 
  18. application into one program file, and to launch it simply on the //e.  
  19. Segments are automatically relocated to appropriate banks of memory, and then 
  20. the application is launched starting at any address in any bank chosen.
  21.  
  22. BUILDAPP.SYSTEM uses a text file as a script for building the application.  
  23. The default name for this text file is BUILDAPP.TEXT.  This can be changed by 
  24. modifying the pathname in the program BUILDAPP.SYSTEM.  The pathname starts at 
  25. the sixth byte of the file, memory location $2006 if BLOADed.  The pathname is 
  26. a pascal string.  (This is the standard ProDOS way of giving the launched 
  27. application a pathname.)
  28.  
  29. To use the BUILDAPP.SYSTEM program, you will need a disk with ProDOS, the 
  30. BUILDAPP.SYSTEM program, a build script file called BUILDAPP.TEXT, and all the 
  31. segments of your application on one disk.  This disk is now bootable.  When 
  32. the disk is booted, BUILDAPP.SYSTEM will construct a single executable block 
  33. of code starting at address $2000.  Then it may or may not prompt you as to 
  34. whether or not you want to save this image.  (The “whether or not” is 
  35. configurable.)  During development, you will often choose not to save it, 
  36. since it takes just that much longer to get the application executing.  Then 
  37. you can test your latest addition or change to your application.  To make a 
  38. bootable disk without BUILDAPP.SYSTEM, you just save the application image to 
  39. disk, and then copy the application to a disk with just ProDOS on it.  If the 
  40. application name ends with .SYSTEM, and it has a filetype of $FF, you have a 
  41. bootable application.
  42.  
  43.  
  44. You may wish to develop on one machine, which writes the segments to the 
  45. ProDOS disk, and then just boot the disk on another machine.  This saves a lot 
  46. of time booting into your development environment.  There is also the 
  47. advantage of always being able to look at the most current source while 
  48. executing the program.  You don't need two machines to develop, but it will 
  49. definitely speed up the add/change/test development cycle every programmer 
  50. goes through.
  51.  
  52.  
  53.  
  54. How the application is built depends on the BUILDAPP.TEXT script file.  Here 
  55. is the explanation of this file:
  56.  
  57. The first line of the build script is the pathname that will be placed at 
  58. $2006 of the application.  You may have no need for this, but if you are 
  59. developing a system application, launchers may place a pathname there, and you 
  60. may want a default.
  61.  
  62. Lines 2-N are for the segments to be loaded.  These lines have 2 or 3 fields,
  63. depending on the bit settings of first field.
  64.  
  65.  
  66. First field bit settings:
  67.  
  68. Bits 0-3 are bank selection bits.  The breakdown is as follows:
  69.  
  70. Bit 0:    Indicates ROM or language card.  Off for ROM, on for language card.
  71. Bit 1:    Indicates which language card (if bit 0 is on).  Off for primary 
  72.         language card, on for auxiliary language card.
  73. Bit 2:    Indicates 1st or 2nd $D000 bank of language card.  Which language card 
  74.         is still indicated by bit 0 and 1.  Off selects the secondary $D000
  75.         bank ($C083), and on selects the primary $D000 bank ($C08B).
  76. Bit 3:    Indicates primary or auxiliary 48k.  Off for primary, on for auxiliary.
  77.  
  78. Bit 4 is used to prevent a system-setup operation that is necessary for 8-bit
  79. applications that use the auxiliary stack.  If it is necessary, then why use
  80. a bit to override it?  The reason for this is that it is necessary only when
  81. an application is first started.  Once it has been done, it does not have to
  82. be done again.  It is possible to sub-launch a second application built with
  83. BUILDAPP.SYSTEM.  This sub-launch should not reinitialize the secondary stack
  84. pointer value.
  85.  
  86. Bit 5 must be off.
  87.  
  88. Bit 6 indicates you wish this segment to be called immediately after it has
  89. been moved.  This allows initialization segments to be called during the
  90. dispatch process.  Initialization segments can not be in auxiliary 48K RAM.
  91. The initialization segment is jsr'ed to, so that after it has completed,
  92. the segment simply does an rts, and the dispatch process is continued.
  93.     Here is an example use of an initial segment:
  94.         You want to put 0's in the secondary $D000 bank of the auxiliary
  95.         language card.  You could do this by having a 4k block of 0's as a
  96.         segment, and then have the dispatcher load that segment into the
  97.         correct $D000 bank.  This, of course adds 4k to the application
  98.         size.  An alternative would be to write an initial segment that
  99.         would fill this $D000 bank with 0's.  The initial segment address
  100.         doesn't have to be in the $D000 address range, yet the bank is
  101.         still selected.  So, you could have some code than executes at
  102.         $0800 that fills $D000-$DFFF with 0's.  Once this is done, you
  103.         would simply rts.  After the job is done, the initial segment
  104.         isn't needed any longer, and you could have a later segment
  105.         load into the $0800 space.
  106.  
  107. Bit 7 of field 1 being on indicates the end of the segment list.  Bits 0-3
  108. still indicate which bank of memory, and the following field indicates the 
  109. launch address within that bank.  The correct bank is selected, and then a
  110. jmp instruction is executed to the designated address.  The only restriction
  111. is that the starting location can not be in auxiliary 48k of RAM.
  112.  
  113. Bits 8-14 must be off.
  114.  
  115. Bit 15 indicates that you are going to use GSBUG in 8-bit mode.  For GSBUG to
  116. work, it must be able to reserve 1024 bytes of consecutive memory in primary
  117. RAM.  GS/OS reserves all of primary RAM (and more) for ProDOS.  It does this
  118. by creating a handle that takes all of RAM from $0800 through $BFFF.  It is
  119. BUILDAPP.SYSTEM that makes the 1024 bytes of RAM allocatable for GSBUG.  It
  120. is not the application dispatcher itself.  If you save the built application
  121. to disk, and then run the built application, no memory will be reserved for
  122. GSBUG.  This is actually a feature.  During the development process, when you
  123. are using BUILDAPP.SYSTEM, you can tell BUILDAPP.SYSTEM to reserve memory
  124. for GSBUG.  When you are done using BUILDAPP.SYSTEM, and you do the final
  125. build of your application, your final application will not do anything special
  126. for GSBUG.  Also, if you need to change which 1024 bytes of memory are used,
  127. you can do this simply by changing the build script for your application.
  128.  
  129. The second field is the load address.  This address is used differently, 
  130. depending on the bit settings of field 1.  If bits 7 and 15 are both off,
  131. then the value in this field indicates where the code or data should be
  132. moved to at application startup time.  If bit 7 is on, then this address
  133. indicates the starting address of the application.  If bit 15 is on, then
  134. this address indicates the start of 1024 bytes of primary 48k memory that
  135. GSBUG will use when invoked.
  136.  
  137. The third field is the name of the segment itself.  This can be a full or 
  138. partial pathname.  There is only a third field if bits 7 and 15 are both off.
  139.  
  140. The next two lines indicate whether you want hex or decimal information 
  141. indicating starting address and total application size.
  142.  
  143. The next line indicates whether or not you want to be prompted to save the 
  144. file, and if you don’t want to be prompted, what to do instead.  To not be 
  145. prompted, the first character of ths line needs to be a Y, N, or Q (or the 
  146. lowercase equivalent).  You will be prompted if the first character of this 
  147. line is anything else.  (Putting a ? here if you want to be prompted isn’t a 
  148. bad idea.  It acts as a placeholder, and is reasonably descriptive.)
  149.  
  150. The final line indicates the application filetype, auxtype, and filename.  The 
  151. application builder will ask if you want the application saved.  After the 
  152. file is saved (or not), the application is launched for testing.
  153.  
  154. NOTE:  All numeric fields can be decimal or hex.
  155.  
  156. The below is a sample build script that was used to make the application 
  157. builder itself.  
  158.  
  159. There is only one segment for this application.  The runtime was linked into 
  160. the main code module, generating only one binary code segment.
  161.  
  162. BUILDAPP.TEXT                    ;The default script filename.
  163. 0,$800,BUILD.BIN                ;The buildapp application.
  164. $80,$800                        ;Starting address.
  165. $                                ;Display starting address in hex.
  166. $                                ;Display application size in hex.
  167. N                                ;Don’t save file -- just launch it.
  168. $FF,0,BUILDAPP.SYSTEM            ;Filetype, auxtype, and filename.
  169.  
  170. The BUILDAPP.TEXT file can be up to 2045 bytes long.
  171.  
  172. Bank switching will still have to occur within the application, as necessary.  
  173. There is no getting around that on a //e.  BUILDAPP.SYSTEM is to simplify the 
  174. loading and starting of an application, by making it a single, launchable 
  175. file.
  176.  
  177.  
  178.  
  179. Below are the macros included in the runtime, and their basic usage:
  180.  
  181. _____________________________________________________________
  182.  
  183. OPERAND USAGE:
  184.  
  185. If the operand represents an integer variable or string, then you do not put a 
  186. # in front of it.  Variables and strings are always either a ldx literal, or a 
  187. ldy literal, so the # is assumed.  When the macro is expanded, the # is put 
  188. there automatically.
  189.  
  190. If the operand represents a value, then you will need to put a # or an * in 
  191. front of the operand.  If you put a # in front of the operand, then it is a 
  192. literal.  If you put an * in front, then it uses the value at that address.  
  193. This is similar to the C unary operator *.
  194.  
  195. If the operand represents a 1-byte value, then you will need to put a < after 
  196. the # or *.  This tells the macros to load only the accumulator with a value 
  197. (instead of the accumulator and y-register) and call the low-byte-only entry 
  198. point instead.
  199.  
  200. An extension has been added in version 3.1.  You can now have as many levels
  201. of indirection as you want.  A single * gives you a single level of indirection.
  202. (Value at, instead of value.)  Two *’s in a row gives you two levels of
  203. indirection.  This would be equivalent to a double-dereference in c.
  204.  
  205. These macros are interfaces for the runtime routines associated with them.  
  206. The runtime routines handle up to 128 integer variables, and up to 256 
  207. strings.  The runtime also has multi-dimension array support.  The integer 
  208. functions are simple add,sub,mul,div, and others.  These others include mass-
  209. initialization, min, max,  print decimal, etc.  The string functions are most 
  210. of what is available in AppleSoft, in various forms.  The array functions are 
  211. used to define a base pointer to a row of dta within the array, and then to 
  212. index into and out of that row.  There is also floating-point support, as well.
  213.  
  214. The principle of the runtime routines is that the xreg holds a destination 
  215. variable number (for ints: 0-254, for strings: 0-255).  All runtimes preserve 
  216. the xreg, therefore, you can do multiple operations to a single variable 
  217. without having to reload the xreg.  The values that are used on the xreg 
  218. variable (the source data), is one of 3 forms for integers:
  219.     1. 1-byte value
  220.     2. 2-byte value
  221.     3. 2-byte integer variable.
  222. 1-byte values are placed in the acc.  2-byte values are placed in the acc,y 
  223. (acc=lo, y=hi).  2-byte integer variables have the variable number placed in 
  224. the yreg.  (The yreg is not preserved by the runtime routines.)  Once the 
  225. source data is loaded (in acc, acc-y, or y), the proper call to the runtime 
  226. routines is made.  The 'proper' routine is based on the type of data the 
  227. source is.  (If the source is a variable, and we are adding, the macro will 
  228. call the addvar routine.)
  229.  
  230. The values that are used on the xreg variable (the source data), is one
  231. of 2 forms for floating-point:
  232.     1. 2-byte pointer to 5-byte AppleSoft floating-point value.
  233.     2. 5-byte floating-point variable.
  234. 2-byte pointers to floating-point values are placed in the acc,y 
  235. (acc=lo, y=hi).  5-byte floating-point variables have the variable number
  236. placed in the yreg.  (The yreg is not preserved by the runtime routines.)
  237. Once the source data is loaded (in acc-y, or y), the proper call to the
  238. runtime routines is made.  The 'proper' routine is based on the type of data
  239. the source is.  (If the source is a variable, and we are adding, the macro
  240. will call the faddvar routine.)
  241.  
  242.  
  243.  
  244. Strings are also referenced by number.  There are 3 tables for strings:
  245.     1. String length table.
  246.     2. Max string length table.
  247.     3. Pointer table.
  248. So, each string takes up four bytes, plus however long the max string length 
  249. is.  Having the pointer allows the program to point into memory that was never 
  250. loaded or initialized.  This can save time loading the application from disk.  
  251. The string routines will never overwrite the buffer space allocated for them.  
  252. The string will be truncated.  So, you can append strings without worry about 
  253. clobbering memory.
  254.  
  255. Some code using the macros and runtime might look like:
  256.  
  257.             _restore    textForBill        ;Point at literal text.
  258.             _readstr    billStr            ;Read text into string.
  259.             _prstr                        ;Print the string.
  260.             _hexpad        #'0'            ;Set hex padding to a 0.
  261.             _rtcout        #'$'            ;Print a $.
  262.             _varcpy        bill,val        ;Set bill to val.
  263.             _addl        ,#5                ;Add 5 to bill.
  264. (****** or:    _add        ,<#5 ******)
  265.             _mulvar        ,factor            ;Multiply bill by factor.
  266.             _vhexout                    ;Print bill in hex.
  267.             rts
  268. textForBill    dc.b        'Bill''s value in hex is:  ',0
  269.  
  270. We could replace the _restore, _readstr, _prstr, with: 
  271. textForBill    _write        'Bill''s value in hex is:  ',0
  272.  
  273. We could still read the text in the _write macro from elsewhere by:
  274.             _restore    textForBill+3    ;Point at literal text.
  275.             _readstr    billStr            ;Read text into string.
  276.  
  277. The +3 skips the jsr to the write routine (generated by _write).  Both the 
  278. _write and _readstr routines stop at a 0.  (The _readstr ending character can 
  279. be changed to whatever you want with the _readend macro, but the default stop 
  280. character is a 0.)
  281.  
  282.  
  283. Below is a list of the macros, and how they are used:
  284.  
  285.  
  286.     acorm
  287.     xcorm
  288.     ycorm
  289.     axcorm
  290.     aycorm
  291.     fparm
  292. These macros are used by other macros for setting up parameters to the routines.
  293. For example:  acorm stands for load A as a Constant OR from Memory.
  294.  
  295.  
  296.     _skipbyte
  297.     _skipword
  298. These macros are use to save bytes.  Instead of jumping around a single byte or
  299. two bytes, skip byte generates a
  300.     dc.b    $24
  301. and _skipword generates a
  302.     dc.b    $2C
  303. These cause the next byte (or 2 bytes) to be skipped.  _skipword must be used
  304. with some caution.  Make sure that the address that is being Bit'ted isn't a
  305. soft-switch, or else you could do something nasty.
  306.  
  307.  
  308.     _int
  309. An alternate form of aycorm.  _int has more meaning to an application.
  310.  
  311.  
  312.     _ptr
  313. An alternate alternate form of aycorm.  Same reason as _int.
  314.  
  315.  
  316.     _byte
  317. An alternate form of acorm.
  318.  
  319.  
  320.     _rtreset
  321. This macro initializes everything necessary in the runtime.  This allows a 
  322. resume after the user presses a reset.    
  323.  
  324.  
  325.     _hibitchrs
  326. This macro is used to turn on the hi-bit for characters that are sent to 
  327. rtcout.
  328.  
  329.  
  330.     _lowbitchrs
  331. This macro is used to turn off the hi-bit for characters that are sent to 
  332. rtcout.
  333.  
  334.  
  335.     _regchrs
  336. This macro is used to make sure that characters sent to rtcout are used as-is.  
  337. There will be no modification of the hi-bit.
  338.  
  339.  
  340.     _rtcout    op
  341. This macro prints a character.  This character is either already in the acc 
  342. (no operand), or what is described by the operand.  The operand can either be 
  343. an absolute or a value in memory.
  344.  
  345.  
  346.     _write op1,op2,op3,...
  347. This macro prints a cstring.  You can use as many operands as MPW allows.  You 
  348. can continue onto the next line with the line continuation character \.  After 
  349. all the operands are processed, the macro places a cstring 0 terminator 
  350. character at the end of the string.  This is done automatically.  Placing one 
  351. there yourself will define an extra one, which will end up being a BRK 
  352. instruction in your code.
  353.  
  354.  
  355.     _writecr
  356. This macro prints a carriage return.
  357.  
  358.  
  359.     _space    op
  360. This macro outputs op number of spaces.  If there is no op, then
  361. the number of spaces to be output is assumed to be in the yreg.
  362.  
  363.  
  364.     _repeat    op
  365. This macro outputs op2 number of the character op1.  If there is no op1,
  366. then the character is assumed to be in the acc.  If there is no op2, then
  367. the number of times the char should be output is assumed to be in the yreg.
  368.  
  369.  
  370.     _wrcstr    op
  371. This macro prints a c string pointed to by the operand.
  372.  
  373.  
  374.     _signed
  375. This macro sets signed mode.  Printing decimal numbers is affected by this.
  376.  
  377.  
  378.     _unsigned
  379. This macro sets unsigned mode.  Printing decimal numbers is affected by this.
  380.  
  381.  
  382.     _chngsgn
  383. This macro does a two's compliment on the variable.  The result is also 
  384. returned in acc,y.
  385.  
  386.  
  387.     _decoutl op
  388. This macro prints a 1-byte decimal value.  This value is either already in the 
  389. acc (no operand), or what is described by the operand.  The operand can either 
  390. be an absolute or a value in memory.
  391.  
  392.  
  393.     _vdecout op
  394. This macro prints a 2-byte decimal value.  This value is stored in a variable.  
  395. The variable number is either already in the xreg (no operand), or is 
  396. determined by the operand.
  397.  
  398.  
  399.     _decout op
  400. This macro prints a 1- or 2-byte decimal value.  This value is either already 
  401. in the acc,y (no operand), or what is described by the operand.  The operand 
  402. can either be an absolute or a value in memory.  This macro optimizes.  If the 
  403. operand is an immediate value, and it is indicated to be a 1-byte value (by 
  404. using <), then code is generated only to load the acc and decoutl is called 
  405. instead of decout.
  406.  
  407.  
  408.     _hexpad op
  409. This macro sets pad mode for hex.  The value is either already in the acc (no 
  410. operand), or what is described by the operand.  The operand can either be an 
  411. absolute or a value in memory.  Printing hex numbers is affected by this.
  412.  
  413.  
  414.     _hexnopad
  415. This macro sets no pad mode for hex.  Printing hex numbers is affected by 
  416. this.
  417.  
  418.  
  419.     _hexoutl op
  420. This macro prints a 1-byte hex value.  This value is either already in the acc 
  421. (no operand), or what is described by the operand.  The operand can either be 
  422. an absolute or a value in memory.  Since it is only printing a 1-byte value, 
  423. the maximum amount of padding is one character.
  424.  
  425.  
  426.     _vhexout op
  427. This macro prints a 2-byte hex value.  This value is stored in a variable.  
  428. The variable number is either already in the xreg (no operand), or is 
  429. determined by the operand.  The maximum amount of padding is three characters.
  430.  
  431.  
  432.     _hexout op
  433. This macro prints a 2-byte hex value.  This value is either already in the 
  434. acc,y (no operand), or what is described by the operand.  The operand can 
  435. either be an absolute or a value in memory.  The maximum amount of padding is 
  436. three characters.
  437.  
  438.  
  439.     _addvar op1,op2
  440. This macro adds a variable to the destination variable.  If there is no op1, 
  441. then the destination variable number is assumed to be in the xreg.  If there 
  442. is no op2, then the source variable number is assumed to be in the yreg.  The 
  443. value of the source variable is returned in acc,y.
  444.  
  445.  
  446.     _addl op1,op2
  447. This macro adds a 1-byte value to the destination variable.  If there is no 
  448. op1, then the destination variable number is assumed to be in the xreg.  If 
  449. there is no op2, then the value is assumed to be in the acc.  The 1-byte value 
  450. is returned in acc.  The yreg is set to 0.
  451.  
  452.  
  453.     _add op1,op2
  454. This macro adds a 2-byte value to the destination variable.  If there is no 
  455. op1, then the destination variable number is assumed to be in the xreg.  If 
  456. there is no op2, then the value is assumed to be in acc,y.  The 2-byte value 
  457. is returned in acc,y.  This macro optimizes.  If op2 is an immediate value, 
  458. and it is indicated to be a 1-byte value (by using <), then code is generated 
  459. only to load the acc and addconl is called instead of addcon.
  460.  
  461.  
  462.     _subvar op1,op2
  463. This macro subtracts a variable from the destination variable.  If there is no 
  464. op1, then the destination variable number is assumed to be in the xreg.  If 
  465. there is no op2, then the source variable number is assumed to be in the yreg.  
  466. The value of the source variable is returned in acc,y.
  467.  
  468.  
  469.     _subl op1,op2
  470. This macro subtracts a 1-byte value from the destination variable.  If there 
  471. is no op1, then the destination variable number is assumed to be in the xreg.  
  472. If there is no op2, then the value is assumed to be in the acc.  The 1-byte 
  473. value is returned in acc.  The yreg is set to 0.
  474.  
  475.  
  476.     _sub op1,op2
  477. This macro subtracts a 2-byte value from the destination variable.  If there 
  478. is no op1, then the destination variable number is assumed to be in the xreg.  
  479. If there is no op2, then the value is assumed to be in acc,y.  The 2-byte 
  480. value is returned in acc,y.  This macro optimizes.  If op2 is an immediate 
  481. value, and it is indicated to be a 1-byte value (by using <), then code is 
  482. generated only to load the acc and subconl is called instead of subcon.
  483.  
  484.  
  485.     _mulvar op1,op2
  486. This macro multiplies the destination variable by a variable.  If there is no 
  487. op1, then the destination variable number is assumed to be in the xreg.  If 
  488. there is no op2, then the source variable number is assumed to be in the yreg.  
  489. The result of the multiply is also returned in acc,y.
  490.  
  491.  
  492.     _mull op1,op2
  493. This macro multiplies the destination variable by a 1-byte value.  If there is 
  494. no op1, then the destination variable number is assumed to be in the xreg.  If 
  495. there is no op2, then the value is assumed to be in the acc.  The result of 
  496. the multiply is also returned in acc,y.
  497.  
  498.  
  499.     _mul op1,op2
  500. This macro multiplies the destination variable by a 2-byte value.  If there is 
  501. no op1, then the destination variable number is assumed to be in the xreg.  If 
  502. there is no op2, then the value is assumed to be in acc,y.   The result of the 
  503. multiply is also returned in acc,y.  This macro optimizes.  If op2 is an 
  504. immediate value, and it is indicated to be a 1-byte value (by using <), then 
  505. code is generated only to load the acc and _mulconl is called instead of 
  506. mulcon.
  507.  
  508.  
  509.     _divvar op1,op2
  510. This macro divides the destination variable by a variable.  If there is no 
  511. op1, then the destination variable number is assumed to be in the xreg.  If 
  512. there is no op2, then the source variable number is assumed to be in the yreg.  
  513. The remainder from the divide is returned in acc,y.
  514.  
  515.  
  516.     _divl op1,op2
  517. This macro divides the destination variable by a 1-byte value.  If there is no 
  518. op1, then the destination variable number is assumed to be in the xreg.  If 
  519. there is no op2, then the value is assumed to be in the acc.  The remainder 
  520. from the divide is returned in acc,y.
  521.  
  522.  
  523.     _div op1,op2
  524. This macro divides the destination variable by a 2-byte value.  If there is no 
  525. op1, then the destination variable number is assumed to be in the xreg.  If 
  526. there is no op2, then the value is assumed to be in acc,y.  The remainder from 
  527. the divide returned in acc,y.  This macro optimizes.  If op2 is an immediate 
  528. value, and it is indicated to be a 1-byte value (by using <), then code is 
  529. generated only to load the acc and _divconl is called instead of divcon.
  530.  
  531.  
  532.     _var op
  533. This macro sets the current variable.  The current variable is defined by a 
  534. number in the xreg.  All runtime functions preserve the xreg, so multiple 
  535. operations can be done to the same variable without having to reload the xreg 
  536. with the variable number.
  537.  
  538.  
  539.     _vderef    op
  540. This macro uses a variable as a pointer and sets that variable to the value to where
  541. that pointer currently points.  The macro preserves all registers.
  542. The c equivalent would be (using longs instead if ints):
  543.     long    *ptrvar;
  544.     ptrvar = (long *)*ptrvar;
  545.  
  546.  
  547.     _set0 op
  548. This macro sets a variable to 0.  If there is no op1, then the destination 
  549. variable number is assumed to be in the xreg.  The acc is set to 0.
  550.  
  551.  
  552.     _varcpy op1,op2
  553. This macro sets a variable to another variable.  If there is no op1, then the 
  554. destination variable number is assumed to be in the xreg.  If there is no op2, 
  555. then the source variable number is assumed to be in the yreg.
  556.  
  557.  
  558.     _setl op1,op2
  559. This macro sets a variable to a 1-byte value.  If there is no op1, then the 
  560. destination variable number is assumed to be in the xreg.  If there is no op2, 
  561. then the value is assumed to be in the acc.
  562.  
  563.  
  564.     _set op1,op2
  565. This macro sets a variable to a 2-byte value.  If there is no op1, then the 
  566. destination variable number is assumed to be in the xreg.  If there is no op2, 
  567. then the value is assumed to be in acc,y.  The 1-byte value is returned in 
  568. acc.  The yreg is set to 0.  This macro optimizes.  If op2 is an immediate 
  569. value, and it is indicated to be a 1-byte value (by using <), then code is 
  570. generated only to load the acc and _setconl is called instead of setcon.
  571.  
  572.  
  573.  
  574.     _setvars op1,op2,op3,op4,...
  575. This macro sets multiple variables to constant values.  The macro is followed 
  576. by as many operands as MPW allows.  The line continuation character \ can be 
  577. used.  The odd operands are the variables to be set, and the even operands are 
  578. the values they should be set to.  Operand1 gets the value of operand 2, and 
  579. so on.  The macro automatically terminates the list with a 255 byte.  This is 
  580. why 255 is not allowed as a variable number.
  581.  
  582.  
  583.     _minswap op1,op2
  584. This macro swaps the two variables if the xreg variable is bigger than the 
  585. yreg variable.  If there is no op1, then the destination variable number is 
  586. assumed to be in the xreg.  If there is no op2, then the source variable 
  587. number is assumed to be in the yreg.
  588.  
  589.  
  590.     _maxswap op1,op2
  591. This macro swaps the two variables if the xreg variable is smaller than the 
  592. yreg variable.  If there is no op1, then the destination variable number is 
  593. assumed to be in the xreg.  If there is no op2, then the source variable 
  594. number is assumed to be in the yreg.
  595.  
  596.  
  597.     _vsgncmp op1,op2
  598. This macro does a signed compare of two variables.  The equal status is true 
  599. if the variables are equal.  If the xreg variable is greater or equal, then 
  600. the carry is set.  If the xreg variable is smaller, then the carry is clear.  
  601. If there is no op1, then the variable number is assumed to be in the xreg.  If 
  602. there is no op2, then the variable number is assumed to be in the yreg.  Once 
  603. op1 and op2 are loaded into the registers, if necessary, the registers are 
  604. preserved.
  605.  
  606.  
  607.     _vcmp op1,op2
  608. This macro does an unsigned compare of two variables.  The equal status is 
  609. true if the variables are equal.  If the xreg variable is greater or equal, 
  610. then the carry is set.  If the xreg variable is smaller, then the carry is 
  611. clear.  If there is no op1, then the variable number is assumed to be in the 
  612. xreg.  If there is no op2, then the variable number is assumed to be in the 
  613. yreg.  Once op1 and op2 are loaded into the registers, if necessary, the 
  614. registers are preserved.
  615.  
  616.  
  617.     _sgncmp op1,op2
  618. This macro works the same as _vsgncmp, except that it compares a variable to a 
  619. constant.  Once op1 and op2 are loaded into the registers, if necessary, the 
  620. registers are preserved.
  621.  
  622.  
  623.     _cmp op1,op2
  624. This macro works the same as _vcmp, except that it compares a variable to a 
  625. constant.  All Once op1 and op2 are loaded into the registers, if necessary, 
  626. the registers are preserved.
  627.  
  628.  
  629.     _rndseed op
  630. This macro is used to seed the random number generator.  If there is no op1, 
  631. then the random seed is assumed to be in the acc,y.
  632.  
  633.  
  634.     _random op
  635. This macro is used to return a random number from 0 to op - 1.  If there is no 
  636. op1, then the random number limit is assumed to be in the acc,y.
  637.  
  638.  
  639.     _strval op
  640. This macro takes the value of a string and returns it in the acc,y.  If there 
  641. is no op1, then the string number is assumed to be in the xreg.
  642.  
  643.  
  644.     _midstrval op1,op2
  645. This macro takes the value of op1 string starting at op2 character and returns 
  646. it in the acc,y.  If there is no op1, then the string number is assumed to be 
  647. in the xreg.  If there is no op2, then the character number is assumed to be 
  648. in the yreg.
  649.  
  650.  
  651.     _prstr op
  652. This macro prints the entire string.  If there is no op1, then the string 
  653. number is assumed to be in the xreg.
  654.  
  655.  
  656. ***************************************
  657.  
  658.  
  659.     _out2str    op
  660. This macro redirects output to the string.  If there is no op1, then
  661. the string number is assumed to be in the xreg.
  662.  
  663.  
  664.     _nullstr    op
  665. This macro clears the string.  If there is no op1, then
  666. the string number is assumed to be in the xreg.
  667.  
  668.  
  669.     _out2stroff
  670. This macro resets output to the setting prior to calling out2str.
  671. out2str can be called multiple times, and only one call to out2stroff
  672. is needed.  (out2str saved the output hook if it is DIFFERENT than
  673. what out2str sets it to.)
  674.  
  675.  
  676.     _prleftstr op1,op2
  677. This macro prints op1 string starting at the first character for op2 
  678. characters.  If there is no op1, then the string number is assumed to be in 
  679. the xreg.  If there is no op2, then the number of characters is assumed to be 
  680. in the acc.
  681.  
  682.  
  683.     _prmidstr op1,op2,op3
  684. This macro prints op1 string starting at the op2 character for op3 characters.  
  685. If there is no op1, then the string number is assumed to be in the xreg.  If 
  686. there is no op2, then the character number is assumed to be in the yreg.  If 
  687. there is no op3, then the number of characters is assumed to be in the acc.
  688.  
  689.  
  690.     _leftstrcpy op1,op2,op3
  691. This macro copies op3 characters from op2 string to op1 string.  If there is 
  692. no op1, then the destination string number is assumed to be in the xreg.  If 
  693. there is no op2, then the source string number is assumed to be in the yreg.  
  694. If there is no op3, then the number of characters is assumed to be in the acc.
  695.  
  696.  
  697.     _strcpy op1,op2
  698. This macro copies op2 string to op1 string.  If there is no op1, then the 
  699. destination string number is assumed to be in the xreg.  If there is no op2, 
  700. then the source string number is assumed to be in the yreg.
  701.  
  702.  
  703.     _midstrcpy op1,op2,op3,op4
  704. This macro copies op4 characters, starting at op3 character from op2 string to 
  705. op1 string.  If there is no op1, then the destination string number is assumed 
  706. to be in the xreg.  If there is no op2, then the source string number is 
  707. assumed to be in the yreg.  If there is no op3, then the character number is 
  708. assumed to be in the acc.  If there is no op4, then all characters to the end 
  709. of the source string will be copied to the destination string.  The op4 case 
  710. is the only case where the assumed value is a particular value (#255), instead 
  711. of what is in a register.  This is the case because there are only three 
  712. registers.
  713.  
  714.  
  715.     _leftstrcat op1,op2,op3
  716. This macro concatenates op3 characters of op2 string onto op1 string.  If 
  717. there is no op1, then the destination string number is assumed to be in the 
  718. xreg.  If there is no op2, then the source string number is assumed to be in 
  719. the yreg.  If there is no op3, then the number of characters is assumed to be 
  720. in the acc.
  721.  
  722.  
  723.     _strcat op1,op2
  724. This macro concatenates op2 string onto op1 string.  If there is no op1, then 
  725. the destination string number is assumed to be in the xreg.  If there is no 
  726. op2, then the source string number is assumed to be in the yreg.
  727.  
  728.  
  729.     _midstrcat op1,op2,op3,op4
  730. This macro concatenates op4 characters starting at op3 character from op2 
  731. string onto op1 string.  If there is no op1, then the destination string 
  732. number is assumed to be in the xreg.  If there is no op2, then the source 
  733. string number is assumed to be in the yreg.  If there is no op3, then the 
  734. character number is assumed to be in the acc.  If there is no op4, then all 
  735. characters to the end of the source string will be concatenated to the 
  736. destination string.  The op4 case is the only case where the assumed value is 
  737. a particular value (#255), instead of what is in a register.  This is the case 
  738. because there are only three registers.
  739.  
  740.  
  741.     _litstr op1,op2,op3,...
  742. This macro works very much like _write, except that the characters are not 
  743. printed.  They are copied into the designated string.  If there is no 
  744. designated string, then it is assumed that the xreg already holds the string 
  745. number.
  746.  
  747.  
  748.     _strchr op1,op2
  749. This macro returns the op2th character of op1 string.  If there is no op1, 
  750. then the destination string number is assumed to be in the xreg.  If there is 
  751. no op2, then the character number is assumed to be in the acc.
  752.  
  753.  
  754.     _strloc op1
  755. This macro returns the physical location of op1 string in memory.  The string 
  756. location is returned in acc,y.If there is no op1, then the destination string 
  757. number is assumed to be in the xreg.
  758.  
  759.  
  760.     _cstr op1,op2,op3,...
  761. This macro is used to generate a cstring using the same syntax as other 
  762. macros.  It works very much like _write and _litstr in the way it handles 
  763. parameters.  The only thing that this macro does, however, is define data.
  764.  
  765.  
  766.     _restore op
  767. This macro sets the read data pointer.  If there is no op, then the address 
  768. for reading data is assumed to be in the acc,y.
  769.  
  770.  
  771.     _readint op
  772. This macro reads an int from the current data pointer and advances the pointer 
  773. by two bytes.  If there is no op1, then the destination variable number is 
  774. assumed to be in the xreg.
  775.  
  776.  
  777.     _readstr op
  778. This macro reads string data into the designated string until the end-of-
  779. string character is encountered.  The data pointer is then set to point after 
  780. this end-of-string character.  If there is no op1, then the destination string 
  781. number is assumed to be in the xreg.
  782.  
  783.  
  784.     _readend op
  785. This macro is used to set the end-of-string character for _readstr.  If there 
  786. is no op1, then the _readstr ending character is assumed to be in the acc.
  787.  
  788.  
  789. The array handling is simple pointer-based storage and retrieval.  There is 
  790. also some logic for multiple-dimensioned arrays.  This system can handle 
  791. arrays up to four dimensions deep.  With a little work, this can be expanded 
  792. to any number.  The system allows for easy expansion to more dimensions.  It 
  793. works by having the application first give a description of the array.  This 
  794. description consists of the location of the array, the size of the elements in 
  795. the array (byte or word), and what size the dimensions are.  There are 
  796. actually four pointers into the array area.  The first one is always the base 
  797. address.  When the base address is first established, all four pointers are 
  798. set to the base address.  If you then wish to index into the array, you tell 
  799. the runtime at what point in the array you wish to access for each level of 
  800. subscript.  If a subscript is omitted at the beginning of the index list, then 
  801. it is assumed that the pointer for that level is already what you want.  If a 
  802. subscript is omitted after the first subscript, then that subscript is assumed 
  803. to be 0.
  804.  
  805. For example:
  806. We have a four dimensional array of words, called things, equated to 
  807. address $4000.  We would declare the array with the _array macro as 
  808. follows:
  809.     _array #things,#2,#3,#4,#5,#6
  810.  
  811. This line means "use the memory at #things as an array of elements that are
  812. 2 bytes each.  (The array access routines will use the element size from the
  813. last _array macro.)  The array is is  3 by 4 by 5 by 6 in size."  The array
  814. handling routines now use this information when getting and putting data to
  815. the array.  The routines only keep track of one array.  If you wish to
  816. switch between two or more arrays, you will have to reissue _array commands.
  817. The _array command does not allocate or protect any memory.  It just gets
  818. the relevant information for the array.  Thus, you can switch arrays as
  819. often as you want.  Of course, there is some time overhead in switching, but
  820. it is rather minimal.
  821.  
  822. If we wished to get the element things(1,3,4,5), and place it in the 
  823. variable thing, we would do the following:
  824.         _index    #1,#3,#4
  825.         _get    thing,#5
  826.  
  827. The _index macro builds pointers for the array into each level of 
  828. subscript.  The _get macro indexes (using #5) from the lowest level 
  829. pointer, and gets that word and stores it in the variable thing.  If we 
  830. then wish to get the element things(1,3,4,4), we would:
  831.         _get    thing,#4
  832.  
  833. We don't have to recalculate any pointers.  They are still intact from 
  834. the above _index macro.  If we wish to change any of the subscripts, 
  835. other than the last one, we will have to issue another _index macro.  
  836. Lets say that we want the element things(1,2,0,5).  Knowing that the 
  837. previous _index macro got the element things(1,3,4,5), we can minimize 
  838. the pointer math by having the _index macro redo only the data that is 
  839. no longer valid.  We would do an _index macro as follows:
  840.         _index    ,#2
  841.         _get    thing,#5
  842.  
  843. The first subscript is the same.  Therefore, the pointer for the first 
  844. subscript is correct.  The pointer for the second subscript is generated 
  845. from the first (just as the pointer for the first is generated from the 
  846. base address of the array).  So, we don't have to mention the first 
  847. subscript again.  Not doing so saves code.  Once any subscript pointer 
  848. is recalculated, all the lower level pointers are set to that value.  
  849. This means that there is an assumption that all the remaining subscripts 
  850. are zero.  If this is indeed the case, they don't have to be mentioned 
  851. either.  In this example, the third subscript is zero.  So, it doesn't 
  852. have to be mentioned either.  This method of separate pointers for 
  853. different levels of the array can be very efficient.  It also can be 
  854. confusing.  If it is not clear whether you can leave subscripts out, 
  855. don't.  It will still work with all of the subscripts, although it will 
  856. be more code than necessary.
  857.  
  858. There is another form of the _index macro.  It is the _vindex macro.  
  859. This is used when the index value is stored in a variable.  One 
  860. unfortunate syntax limitation is that you can't mix the two types on one 
  861. line.  You still can mix the two types, however, when indexing into an 
  862. array.  For example:
  863.     bob = things(color, 3, type, 5)
  864.  
  865. would be done like:
  866.     _vindex        color
  867.     _index        ,#3
  868.     _vindex        ,,type
  869.     _get        bob,#5
  870.  
  871.  
  872. The following macros are used to define and access arrays.
  873.  
  874.     _array loc,elesize,op1,op2,op3,op4
  875. This macro prepares the array handling routines to work on the defined array.  
  876. The operand loc is either the address of the array (when preceded by a # 
  877. sign), or a 2-byte location where the address to the array is stored (when 
  878. preceded by an *).  The operand elesize determines the size of the elements in 
  879. the array.  The elements can be any size, although the element access routines
  880. will only handle 1, 2, and 5 byte sizes for elements.  Operands op1 through op4
  881. describe the dimensions of the array.  These must be constants.  Operands op2
  882. through op4 are optional.  The array may only be linear, in which case, op2
  883. through op4 would have no function.  The operand op1 is actually not used.  It
  884. is just for commenting purposes.  The array routines do not do any range
  885. checking, and all that op1 is good for is to determine if the first subscript
  886. is out of range.  You must have an op1, however, as a placeholder.  This is to
  887. encourage it being used, as it is useful when reading the source code.
  888.  
  889.  
  890.     _index op1,op2,op3
  891. This macro is used to calculate a pointer into the array.  There are actually 
  892. four pointers.  The first three are used as partial results from previous 
  893. calculations, so that all subscripts don't have to be involved every time 
  894. there is a calculation to determine the specific element of the array.  When 
  895. the pointer for op1 is calculated, the resulting offset is added to the base 
  896. array pointer (defined with the _array macro).  This is then stored as the 
  897. 2nd, 3rd, and 4th level pointers.  If there are no more operands, then the 
  898. effective pointer into the array will be this value.  If op2 and op3 were 
  899. zero, then this value would be correct.  The assumption in this case is that 
  900. any undeclared subscripts beyond the first one declared are zero.  So, if your 
  901. array is only two-dimensional, you would then never declare an op2 or op3, and 
  902. they would therefore never affect the pointer into the array.  An interesting 
  903. aside to this is that one array can actually be considered to have a variable 
  904. number of dimensions.  Let's say that you have an array that is 10x10x10.  
  905. This array could also be viewed as a 10x100 array.  Both have the same number 
  906. of elements.  Using the _index macro differently, you could access the array 
  907. either way.  For example:
  908.     _index    #5
  909.     _get    value,#55
  910. would work as well as
  911.     _index    #5,#5
  912.     _get    value,#5
  913. This flexibility can be very useful.  (It can also be confusing.)  If you have 
  914. a case where you know that the first subscript is the same as the last time 
  915. you used the _index (or _vindex) macro, you can choose not to restate that 
  916. subscript.  You might even have a situation where the second subscript is the 
  917. same also.  In these cases, you can choose to leave those operand fields 
  918. empty.  This will produce less code than if you mentioned them.  (There is an 
  919. overhead of 7 bytes per index with the _index macro, and an overhead of 5 
  920. bytes with the _vindex macro.)
  921. The syntax for this would look like:  _index  ,,#5
  922. The commas are necessary to indicate that subscripts 1 and 2 are already 
  923. defined, and that you are referring to subscript 3.  If the commas were not 
  924. there, the _index macro would assume that the #5 is the first subscript, and 
  925. that subscripts 2 and 3 are zero, or not used at all.  This macro optimizes.  
  926. If an operand is an immediate value, and it is indicated to be a 1-byte value 
  927. (by using <), then code is generated only to load the acc and arraylindxN is 
  928. called instead of arrayindxN.
  929.  
  930.  
  931.     _vindex op1,op2,op3
  932. This macro works just like _index, except that the operands are variables, 
  933. instead of constants or values at a particular memory location.  This is 
  934. useful when you want to use variable subscripts.
  935.  
  936.  
  937.     _get op1,op2
  938. This macro is used to get an element from the array.  The operand op2 is 
  939. the right-most subscript in the array.  This value can be either a constant, 
  940. or a value in memory.  The operand op1 is the variable to store the array 
  941. value into.  If the element size is byte, then the hi-byte of the integer
  942. variable will be set to 0.  If the element size is word, then the word is
  943. copied into the integer variable.  If the element size is float, then the
  944. 5-byte element is copied into the variable.
  945.  
  946.  
  947.     _getl op1,op2
  948. This macro is used to get an element from the array using a 1-byte index.  
  949. The operand op2 is the right-most subscript in the array.  This value can be 
  950. either a constant, or a value in memory.  The operand op1 is the variable to 
  951. store the array value into.  (See _get.)
  952.  
  953.  
  954.     _put op1,op2
  955. This macro is used to put an element into the array.  The operand op2 is 
  956. the right-most subscript in the array.  This value can be either a constant, 
  957. or a value in memory.  The operand op1 is the variable that holds the value
  958. to be stored into the array.  
  959.  
  960.  
  961.     _getl op1,op2
  962. This macro is used to put an element into the array using a 1-byte index.  
  963. The operand op2 is the right-most subscript in the array.  This value can be 
  964. either a constant, or a value in memory.  The operand op1 is the variable
  965. that holds the value that will be placed in the array.  (See _put.)
  966.  
  967.  
  968.     _vget op1,op2
  969. This macro works just like _get, except that the operand op2 is a variable.
  970.  
  971.  
  972.     _vput op1,op2
  973. This macro works just like _put, except that the operand op2 is a variable.
  974.  
  975.  
  976.     _getnext op
  977. This macro gets the next element from the current array.
  978.  
  979.  
  980.     _putnext op
  981. This macro puts the next element into the current array.
  982.  
  983.  
  984.  
  985. ***************************************
  986. ***************************************
  987. ***************************************
  988.  
  989.  
  990.     _fstrval    op
  991. This macro takes the value of a string and returns it in the acc,y.
  992. If there is no op1, then the string number is assumed to be in the xreg.
  993.  
  994.  
  995.     _fmidstrval op1,op2
  996. This macro takes the value of op1 string starting at op2 character and
  997. returns it in the acc,y.  If there is no op1, then the string number is
  998. assumed to be in the xreg.  If there is no op2, then the character number
  999. is assumed to be in the yreg.
  1000.  
  1001.  
  1002.     _readfloat op
  1003. This macro reads a float from the current data pointer and advances the
  1004. pointer by five bytes.  If there is no op1, then the destination variable
  1005. number is assumed to be in the xreg.
  1006.  
  1007.  
  1008.     _i2f op
  1009. This macro converts an integer variable into a floating-point variable.
  1010.  
  1011.  
  1012.     _f2i op
  1013. This macro converts a floating-point variable into an integer variable.
  1014.  
  1015.  
  1016.     _fout op
  1017. This macro prints a float value.  fout expects a pointer to the float.
  1018. The pointer is either already in a,y (no operand), or is
  1019. determined by the operand.
  1020.  
  1021.  
  1022.     _fvout op
  1023. This macro prints a float value.  This value is stored in a variable.
  1024. The variable number is either already in the xreg (no operand), or is
  1025. determined by the operand.
  1026.  
  1027.  
  1028.     _fmulvar op1,op2
  1029. This macro multiplies the destination float variable by a float variable.
  1030. If there is no op1, then the destination variable number is assumed to be
  1031. in the xreg.  If there is no op2, then the source variable number is
  1032. assumed to be in the yreg.
  1033.  
  1034.  
  1035.     _fmul op1,op2
  1036. This macro multiplies the destination float variable by a float constant.
  1037. If there is no op1, then the destination variable number is assumed to be
  1038. in the xreg.  If there is no op2, then the source float pointer is
  1039. assumed to be in a,y.
  1040.  
  1041.  
  1042.     _fdivvar op1,op2
  1043. This macro divides the destination float variable by a float variable.
  1044. If there is no op1, then the destination variable number is assumed to be
  1045. in the xreg.  If there is no op2, then the source variable number is
  1046. assumed to be in the yreg.
  1047.  
  1048.  
  1049.     _fdiv op1,op2
  1050. This macro divides the destination float variable by a float constant.
  1051. If there is no op1, then the destination variable number is assumed to be
  1052. in the xreg.  If there is no op2, then the source float pointer is
  1053. assumed to be in a,y.
  1054.  
  1055.  
  1056.     _faddvar op1,op2
  1057. This macro adds a float variable to the destination float variable.
  1058. If there is no op1, then the destination variable number is assumed to be
  1059. in the xreg.  If there is no op2, then the source variable number is
  1060. assumed to be in the yreg.
  1061.  
  1062.  
  1063. This macro adds a float constant the destination float variable.
  1064. If there is no op1, then the destination variable number is assumed to be
  1065. in the xreg.  If there is no op2, then the source float pointer is
  1066. assumed to be in a,y.
  1067.     _fadd op1,op2
  1068.  
  1069.  
  1070.     _fsubvar op1,op2
  1071. This macro subtracts a float variable from the destination float variable.
  1072. If there is no op1, then the destination variable number is assumed to be
  1073. in the xreg.  If there is no op2, then the source variable number is
  1074. assumed to be in the yreg.
  1075.  
  1076.  
  1077.     _fsub op1,op2
  1078. This macro subtracts a float constant from the destination float variable.
  1079. If there is no op1, then the destination variable number is assumed to be
  1080. in the xreg.  If there is no op2, then the source float pointer is
  1081. assumed to be in a,y.
  1082.  
  1083.  
  1084.     _fv2v    op1,op2
  1085. This macro raises the destination float variable by the source float variable.
  1086. If there is no op1, then the destination variable number is assumed to be in
  1087. the xreg.  If there is no op2, then the source variable number is assumed to
  1088. be in the yreg.
  1089.  
  1090.  
  1091.     _fv2con    op1,op2
  1092. This macro raises the destination float variable by the a float constant.
  1093. If there is no op1, then the destination variable number is assumed to be
  1094. in the xreg.  If there is no op2, then the source float pointer is
  1095. assumed to be in a,y.
  1096.  
  1097.  
  1098.     _fsgn op
  1099. This macro gets the sign of the destination float variable and stores it in
  1100. the destination variable.  If there is no op, then the destination variable
  1101. number is assumed to be in the xreg.
  1102.  
  1103.  
  1104.     _fabs op
  1105. This macro gets the absolute value of the destination float variable and
  1106. stores it in the destination variable.  If there is no op, then the
  1107. destination variable number is assumed to be in the xreg.
  1108.  
  1109.  
  1110.     _fint op
  1111. This macro gets the integer value of the destination float variable and
  1112. stores it in the destination variable.  If there is no op, then the
  1113. destination variable number is assumed to be in the xreg.
  1114.  
  1115.  
  1116.     _fsqr op
  1117. This macro gets the square root of the destination float variable and
  1118. stores it in the destination variable.  If there is no op, then the
  1119. destination variable number is assumed to be in the xreg.
  1120.  
  1121.  
  1122.     _flog op
  1123. This macro gets the log base e of the destination float variable and
  1124. stores it in the destination variable.  If there is no op, then the
  1125. destination variable number is assumed to be in the xreg.
  1126.  
  1127.  
  1128.     _fexp op
  1129. This macro raises e to the destination float variable power and
  1130. stores it in the destination variable.  If there is no op, then the
  1131. destination variable number is assumed to be in the xreg.
  1132.  
  1133.  
  1134.     _frnd op
  1135. This macro forms a 'random' number and stores it in the destination
  1136. variable.  If there is no op, then the destination variable number
  1137. is assumed to be in the xreg.
  1138.  
  1139.  
  1140.     _fcos op
  1141. This macro gets the cos of the destination float variable and
  1142. stores it in the destination variable.  If there is no op, then the
  1143. destination variable number is assumed to be in the xreg.
  1144.  
  1145.  
  1146.     _fsin op
  1147. This macro gets the sin of the destination float variable and
  1148. stores it in the destination variable.  If there is no op, then the
  1149. destination variable number is assumed to be in the xreg.
  1150.  
  1151.  
  1152.     _ftan op
  1153. This macro gets the tan of the destination float variable and
  1154. stores it in the destination variable.  If there is no op, then the
  1155. destination variable number is assumed to be in the xreg.
  1156.  
  1157.  
  1158.     _fatn op
  1159. This macro gets the arctan of the destination float variable and
  1160. stores it in the destination variable.  If there is no op, then the
  1161. destination variable number is assumed to be in the xreg.
  1162.  
  1163.  
  1164.     _i2fsetl op1,op2
  1165. This macro sets a float variable to a 1-byte value.  If there is no op1,
  1166. then the destination variable number is assumed to be in the xreg.  If
  1167. there is no op2, then the value is assumed to be in the acc.
  1168.  
  1169.  
  1170.     _i2fset op1,op2
  1171. This macro sets a float variable to a 2-byte value.  If there is no op1,
  1172. then the destination variable number is assumed to be in the xreg.  If
  1173. there is no op2, then the value is assumed to be in the acc.
  1174.  
  1175.  
  1176.     _i2fsetvars
  1177. This macro is used to set a bunch of float variables to integer constant
  1178. values.  There must be a non-zero even number of parameters.  The odd
  1179. parameters are the variables, and the even parameters are the constant
  1180. values for the preceeding parameter.  The setvars routine uses the
  1181. return address as a pointer to the data (just like the write routine).
  1182. It simply sets the designated variable to the designated constant until
  1183. it encounters a 255 as a variable value.  A 255 is reserved for this
  1184. purpose.  This macro places a 255 at the end of the data list
  1185. automatically.
  1186.  
  1187.  
  1188.     _fsetvars
  1189. This macro is used to set a bunch of float variables to float constant
  1190. values.  There must be a non-zero even number of parameters.  The odd
  1191. parameters are the variables, and the even parameters are the constant
  1192. values for the preceeding parameter.  The setvars routine uses the
  1193. return address as a pointer to the data (just like the write routine).
  1194. It simply sets the designated variable to the designated constant until
  1195. it encounters a 255 as a variable value.  A 255 is reserved for this
  1196. purpose.  This macro places a 255 at the end of the data list
  1197. automatically.
  1198.  
  1199.  
  1200.     _fset op1,op2
  1201. This macro sets the destination float variable to a float constant.
  1202. If there is no op1, then the destination variable number is assumed to be
  1203. in the xreg.  If there is no op2, then the source float pointer is
  1204. assumed to be in a,y.
  1205.  
  1206.  
  1207.     _fset0 op
  1208. This macro sets the destination float variable to 0.
  1209.  
  1210.  
  1211.     _fvcmp op1,op2
  1212. This macro compares the destination float variable with a float variable.
  1213. If there is no op1, then the destination variable number is assumed to be
  1214. in the xreg.  If there is no op2, then the source variable number is
  1215. assumed to be in the yreg.  The equal status is true if the variables are
  1216. equal.  If the xreg variable is greater or equal, then the carry is set.
  1217. If the xreg variable is smaller, then the carry is clear.  
  1218.  
  1219.  
  1220.     _fcmp op1,op2
  1221. This macro compares the destination float variable with a float constant.
  1222. If there is no op1, then the destination variable number is assumed to be
  1223. in the xreg.  If there is no op2, then the source variable number is
  1224. assumed to be in the yreg.  The equal status is true if the values are
  1225. equal.  If the xreg variable is greater or equal, then the carry is set.
  1226. If the xreg variable is smaller, then the carry is clear.  
  1227.  
  1228.  
  1229.     _fvarcpy op1,op2
  1230. This macro sets a float variable to another float variable.  If there is
  1231. no op1, then the destination variable number is assumed to be in the
  1232. xreg.  If there is no op2, then the source variable number is assumed
  1233. to be in the yreg.
  1234.  
  1235.  
  1236.     _asc2fp op
  1237. This macro generates an AppleSoft floating-point number.
  1238. It is generated in-line, with a dc.b statement.
  1239.  
  1240.